package com.acme.bankapp.service.bank;

import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import com.acme.bankapp.domain.account.Account;
import com.acme.bankapp.domain.account.CheckingAccount;
import com.acme.bankapp.domain.account.SavingAccount;
import com.acme.bankapp.domain.client.Client;
import com.acme.bankapp.domain.client.Gender;
import com.acme.bankapp.domain.exceptions.InvalidFeedDataException;

public class BankDataParser {
	private final static String ACCOUNT_TYPE_KEY = "accounttype";
	private final static String ACCOUNT_ID_KEY = "accountid";
	private final static String BALANCE_KEY = "balance";
	private final static String OVERDRAFT_KEY = "overdraft";
	private final static String NAME_KEY = "name";
	private final static String GENDER_KEY = "gender";
	
	private final static String CHECKING_ACCOUNT_CODE = "c";
	private final static String SAVING_ACCOUNT_CODE = "s";
	private final static String GENDER_MALE_CODE = "m";
	private final static String GENDER_FEMALE_CODE = "f";

	
	public Gender getGenderByCode(String code) throws InvalidFeedDataException {
		if (GENDER_MALE_CODE.equals(code))
			return Gender.MALE;
		if (GENDER_FEMALE_CODE.equals(code))
			return Gender.FEMALE;
		throw new InvalidFeedDataException("Invalid " + 
						GENDER_KEY + " value: " + code);
	}
	
	public Account getAccount(String accountId, String typeCode,  
							   String balance, String overdraft) 
									  throws InvalidFeedDataException {
		int id = accountId != null ? Integer.parseInt(accountId) : 0;
		double balanceValue = balance != null ? Double.parseDouble(balance) : 0.d;
		double overdraftValue = overdraft != null ? Double.parseDouble(overdraft) : 0.d;
		
		if (CHECKING_ACCOUNT_CODE.equals(typeCode)) {
			return new CheckingAccount(id, balanceValue, overdraftValue);
		} else if (SAVING_ACCOUNT_CODE.equals(typeCode)) {
			return new SavingAccount(id, balanceValue);
		} else {
			throw new InvalidFeedDataException("Invalid " + 
					ACCOUNT_TYPE_KEY + " value: " + typeCode);
		}
	}
	
	public Client readClientFromLine(String str) throws InvalidFeedDataException {
		Client client = null;
		StringTokenizer tokenizer = new StringTokenizer(str, ";");
		Map<String, String> clientFeedFields = new HashMap<String, String>();
		while (tokenizer.hasMoreElements()) {
			String token = tokenizer.nextToken();
			String[] pair = token.split("=");
			clientFeedFields.put(pair[0], pair[1]);
		}
		client = new Client(clientFeedFields.get(NAME_KEY),
							getGenderByCode(clientFeedFields.get(GENDER_KEY)));
		client.setAccount(getAccount(clientFeedFields.get(ACCOUNT_ID_KEY),
									 clientFeedFields.get(ACCOUNT_TYPE_KEY), 
									 clientFeedFields.get(BALANCE_KEY),
									 clientFeedFields.get(OVERDRAFT_KEY)));
		return client;
	}
}
